package id.co.shuba.spamobile.task;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import id.co.shuba.spamobile.App;
import id.co.shuba.spamobile.Configs;
import id.co.shuba.spamobile.Encryptor;
import id.co.shuba.spamobile.Sessions;
import id.co.shuba.spamobile.WSException;
import id.co.shuba.spamobile.activities.FormPipelineActivity;
import id.co.shuba.spamobile.data.AreaDB;
import id.co.shuba.spamobile.data.BaseDB;
import id.co.shuba.spamobile.data.DSARDB;
import id.co.shuba.spamobile.data.DatabaseHandler;
import id.co.shuba.spamobile.data.HolidayDB;
import id.co.shuba.spamobile.data.StandardDB;
import id.co.shuba.spamobile.data.ProspectDB;
import id.co.shuba.spamobile.data.ProspectProgressDB;
import id.co.shuba.spamobile.model.DSARInfo;
import id.co.shuba.spamobile.model.ProspectInfo;
import id.co.shuba.spamobile.model.ProspectProgressInfo;
import id.co.shuba.spamobile.model.UserInfo;
import id.co.shuba.spamobile.services.WebServiceHelper;
import id.co.shuba.spamobile.util.Base64;
import id.co.shuba.spamobile.util.Str;
import android.app.ProgressDialog;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Path.FillType;
import android.os.AsyncTask;
import android.util.Log;

public class DownloadProspectRefferalTask extends BaseProgressTask {
	WebServiceHelper _ws;
	SQLiteDatabase _db;		
	INotify _notify;
	UserInfo _user;
	String _imei;
	String _dateStart;
	String _dateEnd;
	int _guFup;	

	public DownloadProspectRefferalTask(WebServiceHelper ws, SQLiteDatabase db,
			INotify notify, UserInfo user, String imei, int guFup) {
		_ws = ws;
		_db = db;						
		_notify = notify;
		_user = user;
		_imei = imei;	
		_guFup = guFup;		
	}
	
	@Override
	protected AsyncTaskResult<Void> doInBackground(Object... params) {
		try {						
			Encryptor enc = new Encryptor(
					Encryptor.ENC_AES,
					Encryptor.ENC_AES, App.createCompleteKey(_user.getEncryptionKey()), App.IV);
			String pwd = enc.decryptText(_user.getPassword());	
			
			Map<String, Object> properties = new HashMap<String, Object>();
			properties.put("aoCode", _user.getAoCode());
			properties.put("unitCode", _user.getUnitCode());			
			properties.put("nip", _user.getNip());
			properties.put("password", pwd);
			properties.put("imei", _imei);
			properties.put("token", _user.getToken());			
						
			publishStatus("Downloading Prospect...");
			String result = _ws.Call("GetProspectRefferal", properties).toString();
			publishProgress(20);
						
			publishStatus("Extracting Result...");
			String strJSON = new String(Base64.decode(result, Base64.GZIP)); 			
			publishProgress(30);			
			
			JSONObject res = new JSONObject(strJSON);
			String error = res.getString("error");
			if (error.length() > 0 && !error.equals("null"))
				throw new WSException(error);
				
			JSONArray jsonArray = res.getJSONArray("result");												
			publishProgress(50);
			
			List<String> ids = new ArrayList<String>();
			publishStatus("Updating...");
			int length = jsonArray.length();						
			for (int i = 0; i < length; i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);				
				ProspectInfo info = new ProspectInfo();				
																		
				String dateFollowUp = HolidayDB.addDays(_db, App.processDate, _guFup);				
				Date assignedDate = BaseDB.parseDate(getString(jsonObject, "assignedDate"));
				if (assignedDate == null)
					Log.d("Download", "Download Prospect Refferal: assignedDate null");
				
				assignedDate = HolidayDB.addDays2(_db, assignedDate, _guFup);				
				
				String address = getString(jsonObject, "addressBusiness");
				boolean isRjs = assignedDate.getTime() > App.getMinDate().getTime() &&  App.processDate.getTime() > assignedDate.getTime();
				
				String unitCodeDest = getString(jsonObject, "unitCodeDest");
				String prospectID = App.createProspectID(unitCodeDest, _user.getAoCode());                
                if (address.trim().length() > 255) address = address.substring(0, 255);
                	                
				info.setId(prospectID);
				info.setProspectNo("n/a");
				info.setUnitCode(unitCodeDest);
				info.setSourceCode(_user.getSourceCode());
				info.setAoCode(getString(jsonObject, "assignedTo"));
				info.setFullName(getString(jsonObject, "fullName"));
				info.setJenisUsaha(getString(jsonObject, "jenisUsaha"));
				info.setRencanaPlafon(jsonObject.getLong("rencanaPlafon"));				
				info.setOfficePhone(getString(jsonObject, "officePhone"));
				info.setAddressBusiness(address);				
				info.setProgressStatus("NEW");
				info.setEntryBy(_user.getNip());
				info.setEntryDate(App.getProcessDateTime());
				info.setGuFup(isRjs? BaseDB.dateFormat.format(assignedDate) : dateFollowUp);
								
				ProspectDB.addOrUpdateProspectRefferal(_db, info);
				
				ProspectProgressInfo progressInfo = new ProspectProgressInfo();
				progressInfo.setProspectID(info.getProspectID());
				progressInfo.setProgressStatus(info.getProgressStatus());
				progressInfo.setEntryBy(info.getEntryBy());
				progressInfo.setEntryDate(info.getEntryDate());
				progressInfo.setUpdateBy(info.getEntryBy());
				progressInfo.setUpdateDate(info.getEntryDate());
								
				ProspectProgressDB.addOrUpdate(_db, progressInfo);
				
				if (isRjs) {										
					ProspectInfo p2 = new ProspectInfo();
					p2.setId(info.getProspectID());
					p2.setUpdateBy(info.getEntryBy());
					p2.setUpdateDate(info.getEntryDate());
					p2.setProgressStatus("RJS");
					p2.setProspectFinishTime(info.getEntryDate());					
					ProspectDB.updateProspectFinishTime(_db, p2);
				}
								
				int visitNo = DSARDB.generateVisitNo(_db, "") + 1;
				DSARInfo visit = new DSARInfo();
				visit.setProspectID(info.getProspectID());
				visit.setVisitNo(visitNo);
				visit.setDateVisitPlan(info.getEntryDate());
				visit.setEntryBy(info.getEntryBy());
				visit.setEntryDate(info.getEntryDate());
				visit.setUpdateBy(info.getEntryBy());
				visit.setUpdateDate(info.getEntryDate());
				visit.setIsUpload("0");
				visit.setIsDeleted("0");
												
				DSARDB.addOrUpdate(_db, visit);				
				
				ids.add(getString(jsonObject, "refferalID"));
				
				int progress = (int)(50 + (50f * (((float)i)/length)));
				publishStatus(String.format("Updating Prospect Refferal...%d/%d", i, length));
				publishProgress(progress);
				
				Thread.sleep(1000);
			}
			
			if (ids.size() > 0) {
				properties.clear();
				properties.put("nip", _user.getNip());
				properties.put("password", pwd);
				properties.put("imei", _imei);
				properties.put("token", _user.getToken());
				properties.put("data", Str.join(ids, ","));
				
				result = _ws.Call("UpdateProspectRefferal", properties).toString();
				
				strJSON = new String(Base64.decode(result, Base64.GZIP)); 									
				
				res = new JSONObject(strJSON);
				error = res.getString("error");
				if (error.length() > 0 && !error.equals("null"))
					throw new WSException(error);
			}			
			
			publishProgress(0);
			publishStatus("Done!");
			
			return new AsyncTaskResult<Void>((Void) null);
		} catch (WSException we) {
			publishStatus(we.getMessage());
			publishProgress(0);
			return new AsyncTaskResult<Void>(we);
		} catch (Exception e) {
			Log.e("Download", e.getMessage(), e);
			if (e.getMessage().contains("Unable to resolve") || e.getMessage().contains("failed to connect")) {
				publishStatus("Tidak dapat tersambung ke server");
			} else {
				publishStatus(e.getMessage());
			}
			publishProgress(0);
			return new AsyncTaskResult<Void>(e);
		}		
	}		
	
	private String getString(JSONObject obj, String name) throws JSONException {
		String a = obj.getString(name);
		if (a != null) a = a.trim();
		if ("null".equals(a)) return null;
		return a;
	}
	
	@Override
	public String getTitle() {		
		return "Prospect Refferal";
	}
	
	@Override
	protected void onPostExecute(AsyncTaskResult<Void> result) {		
		super.onPostExecute(result);
		
		_notify.notifyFinish(result.getError());
	}
	
	@Override
	protected void onCancelled(AsyncTaskResult<Void> result) {		
		super.onCancelled(result);
		
		Log.d("DownloadProspectRefferal", "Task cancelled");
	}	
}
